<template>
  <vxe-grid
    :class="{ 'always-border': alwaysBorder, disabled }"
    ref="xGrid"
    v-bind="$attrs"
    :data="rows"
    v-on="$listeners"
    :loading="loading"
    :editConfig="mEditConfig"
    :filter-config="{
      iconNone: 'el-icon-arrow-down',
      iconMatch: 'el-icon-arrow-down',
    }"
    :columns="mColumns"
  >
    <div v-if="page" data-flex="main:right" class="page p-v-10" slot="pager">
      <el-pagination
        v-bind="mPage"
        :current-page="pageNo"
        :page-sizes="pageSizes"
        :page-size="pageSize"
        @current-change="onPageNumChange"
        @size-change="onSizeChange"
        :total="total"
      >
      </el-pagination>
    </div>
  </vxe-grid>
</template>

<script>
export default {
  name: 'OsGrid',
  props: {
    columns: Array,
    alwaysBorder: { type: Boolean, default: true },
    data: Array,
    disabled: Boolean,
    otherSearch: Object, // 自定义查询动作
    editConfig: {},
    page: { type: [Object, Boolean], default: false },
    autoLoad: { type: Boolean, default: true },
    action: String,
    size: String,
    tApi: Object
  },
  data () {
    return {
      loading: false,
      defaultPageSizes: [10, 20, 50, 100, 200, 300, 400],
      pageNo: this.page?.pageNo || 1,
      pageSize: this.page?.pageSize || 10,
      total: 0,
      rows: [],
      mData: this.data ? [...this.data] : null,
      sort: {}
    }
  },
  computed: {
    pageSmall () {
      return ['small', 'mini'].includes(this.size)
    },
    mPage () {
      return {
        small: this.pageSmall,
        background: !this.pageSmall,
        layout: this.page?.layout || 'total, sizes, prev, pager, next, jumper',
        ...this.page
      }
    },
    pageSizes () {
      const pageSizes = this.page?.pageSizes || this.defaultPageSizes
      const list = [...new Set([...pageSizes, this.pageSize])]
      list.sort((a, b) => a - b)
      return list
    },
    mEditConfig () {
      if (this.editConfig && !this.editConfig.activeMethod) {
        return {
          ...this.editConfig,
          activeMethod: () => !this.disabled
        }
      }
      return this.editConfig
    },
    mColumns () {
      // 转换一下属性兼容qxTable的配置方式
      return (this.columns || []).map((item) => {
        const { prop, label, renderCell, ...obj } = item
        obj.field = prop || item.field
        obj.title = label || item.title
        if (obj.type && obj.type === 'index') {
          obj.type = 'seq'
          obj.width = obj.width || '48px'
        }
        if (obj.type && obj.type === 'selection') {
          obj.type = 'checkbox'
          obj.width = obj.width || '48px'
          obj.title = ''
        }
        if (renderCell) {
          obj.slots = {
            default: (data) => [
              item.renderCell({ ...data, updateData: this.updateData })
            ]
          }
        }
        // options
        if (obj.editRender && typeof obj.editRender.options === 'function') {
          obj.editRender.options().then((data) => {
            obj.editRender.options = data
          })
        }
        // filters
        if (obj.filters) {
          const texts = [
            ...new Set((this.data || []).map((row) => row[obj.field]))
          ]
          if (Array.isArray(obj?.editRender?.options)) {
            obj.filters = obj.editRender.options
          } else {
            obj.filters = texts.map((t) => ({ label: t || '空', value: t }))
          }
          // item.filterMethod = item.filterMethod || ((value, row, column) => row[column.property] === value)
        }
        return obj
      })
    },
    isAutoFilters () {
      return this.columns.some((c) => c.filters)
    }
  },
  watch: {
    data (val) {
      this.mData = [...val]
      this.getData()
    },
    columns () {
      // this.$refs.xGrid.reloadColumn(this.mColumns)
    }
  },
  mounted () {
    this.autoLoad && this.getData()
    this.$emit('update:tApi', this.getGrid())
  },
  methods: {
    async getData () {
      if (this.mData) {
        // 本地数据
        if (this.page) {
          this.rows = this.mData.slice(
            (this.pageNo - 1) * this.pageSize,
            this.pageNo * this.pageSize
          )
          this.total = this.mData.length
        } else {
          this.rows = this.mData
        }
        this.selectData() // 选中数据
      } else if (this.action) {
        this.loading = true
        const { component, rows, formData, ...params } = this.getCbData()
        const { data } = await this.$store.dispatch(this.action, {
          ...formData,
          ...params
        })
        this.loading = false
        if (data) {
          this.rows = data.rows || data.records || data.list
          this.total = data.total
          this.selectData() // 选中数据
        } else {
          this.total = 0
          this.rows = []
        }
      }
    },
    getCbData () {
      const { search, clear, ...formData } = this.form
        ? this.mFApi.formData()
        : {}
      const re = {
        formData: { ...formData, ...this.otherSearch },
        rows: this.rows,
        pageSize: this.pageSize,
        pageNo: this.pageNo,
        component: this
      }
      if (!this.$utils.isEmptyObject(this.sort)) {
        re.sort = this.sort
      }
      return re
    },
    selectData () {
      // this.$parent.selectData()
      this.$emit('selectData', this.rows)
    },
    onPageNumChange (pageNo) {
      this.pageNo = pageNo
      this.getData()
    },
    onSizeChange (pageSize) {
      this.pageNo = 1
      this.pageSize = pageSize
      this.getData()
    },
    updateData (row, field) {
      const xGrid = this.$refs.xGrid
      if (xGrid.isUpdateByRow(row)) {
        this.loading = true
        setTimeout(() => {
          xGrid.reloadRow(row, null, field)
          this.$utils.message.success('保存成功')
          this.loading = false
          xGrid.clearActived()
        }, 500)
      } else {
        console.log('数据未改动')
      }
    },
    getGrid () {
      return this.$refs.xGrid
    },
    getRows () {
      return this.rows
    }
  }
}
</script>

<style lang="scss" scoped>
.always-border /deep/ .col--edit:not(col--actived) .vxe-cell--label {
  width: 100%;
  display: inline-block;
  border: 1px solid #dcdfe6;
  height: 32px;
  line-height: 32px;
  border-radius: 4px;
  padding: 0 15px;
}
.disabled /deep/ .col--edit:not(col--actived) .vxe-cell--label {
  border: none;
}
/deep/ .size--small .vxe-table--footer-wrapper.body--wrapper {
  margin-top: -2px !important;
  background-color: #f5f7fa;
}

/deep/ .vxe-table--filter-wrapper {
  li {
    display: flex;
    align-items: center;
    align-content: center;
    .vxe-checkbox--icon {
      display: inline-block;
      margin-top: 5px;
    }
  }
  .vxe-table--filter-header {
    display: none;
  }
  .vxe-table--filter-body {
    min-height: 20px;
  }
  .vxe-table--filter-footer {
    height: 35px;
    line-height: 18px;
  }
}
</style>
